/*
 * Copyright (c) 2002-2003 by OpenSymphony
 * All rights reserved.
 */
package com.company.workflow.loader;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.opensymphony.workflow.InvalidWorkflowDescriptorException;
import com.opensymphony.workflow.loader.ActionDescriptor;
import com.opensymphony.workflow.loader.ValidationHelper;
import com.opensymphony.workflow.util.Validatable;


public class ResultDescriptor extends AbstractDescriptor implements Validatable 
{
    //~ Instance fields ////////////////////////////////////////////////////////
    protected List postFunctions = new ArrayList();
    protected List preFunctions = new ArrayList();
    protected List validators = new ArrayList();
    protected String dueDate;
    protected String oldStatus;
    protected String owner;
    protected String status;
    protected boolean hasStep = false;
    protected int join;
    protected int split;
    protected int step = 0;
    protected List conditions = new ArrayList();

    //~ Constructors ///////////////////////////////////////////////////////////

    public ResultDescriptor() {
    }


    //~ Methods ////////////////////////////////////////////////////////////////
    public String getDueDate() {
        return dueDate;
    }

    public void setJoin(int join) {
        this.join = join;
    }

    public int getJoin() {
        return join;
    }

    public void setOldStatus(String oldStatus) {
        this.oldStatus = oldStatus;
    }

    public String getOldStatus() {
        return oldStatus;
    }

    public void setOwner(String owner) {
        this.owner = owner;
    }

    public String getOwner() {
        return owner;
    }

    public List getPostFunctions() {
        return postFunctions;
    }

    public List getPreFunctions() {
        return preFunctions;
    }

    public void setSplit(int split) {
        this.split = split;
    }

    public int getSplit() {
        return split;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getStatus() {
        return status;
    }

    public void setStep(int step) {
        this.step = step;
        hasStep = true;
    }

    public int getStep() {
        return step;
    }

    public List getValidators() {
        return validators;
    }

    public List getConditions() {
        return conditions;
    }

    public void validate() throws InvalidWorkflowDescriptorException {
        ValidationHelper.validate(preFunctions);
        ValidationHelper.validate(postFunctions);
        ValidationHelper.validate(validators);

        //if it's not a split or a join, then we require a next step
        if ((split == 0) && (join == 0)) {
            StringBuffer error = new StringBuffer("Result ");

            if (this.getId() > 0) {
                error.append("#").append(getId());
            }

            error.append(" is not a split or join, and has no ");

            if (!hasStep) {
                throw new InvalidWorkflowDescriptorException(error.append("next step").toString());
            }

            if ((status == null) || (status.length() == 0)) {
                throw new InvalidWorkflowDescriptorException(error.append("status").toString());
            }
        }

        if (conditions.size() == 0) {
        	
            //throw new InvalidWorkflowDescriptorException("Conditional result from " + ((ActionDescriptor) super.getParent()).getName() + " to " + getDestination() + " must have at least one condition");
        }

        ValidationHelper.validate(conditions);
    }
    
    public String getXML() {

        StringBuffer buf = new StringBuffer();
        buf.append("<result");

        if (hasId()) {
            buf.append(" id=\"").append(getId()).append("\"");
        }

        buf.append(" old-status=\"").append(oldStatus).append("\"");

        if (join != 0) {
            buf.append(" join=\"").append(join).append("\"");
        } else if (split != 0) {
            buf.append(" split=\"").append(split).append("\"");
        } else {
            buf.append(" status=\"").append(status).append("\"");
            buf.append(" step=\"").append(step).append("\"");

            if ((owner != null) && (owner.length() > 0)) {
                buf.append(" owner=\"").append(owner).append("\"");
            }
        }

        buf.append(">");

        for (int i = 0; i < conditions.size(); i++) {
            ConditionsDescriptor condition = (ConditionsDescriptor) conditions.get(i);
            buf.append(condition.getXML());
        }

        /*
        if (validators.size() > 0) {
        	
        	buf.append("<validators>");

            for (int i = 0; i < validators.size(); i++) {
                ValidatorDescriptor validator = (ValidatorDescriptor) validators.get(i);
                validator.writeXML(out, indent);
            }

            buf.append("</validators>");
        }
        */

        printPreFunctions(buf);
        printPostFunctions(buf);
        buf.append("</result>");
        
        return buf.toString();
    }
    


    private String getDestination() {
        if (join != 0) {
            return "join #" + join;
        } else if (split != 0) {
            return "split #" + split;
        } else {
            return "step #" + step;
        }
    }
    
    protected void printPreFunctions(StringBuffer buf) {
        if (preFunctions.size() > 0) {
            buf.append("<pre-functions>");

            Iterator iter = preFunctions.iterator();

            while (iter.hasNext()) {
                FunctionDescriptor function = (FunctionDescriptor) iter.next();
                buf.append(function.getXML());
            }

            buf.append("</pre-functions>");
        }
    }
    
    protected void printPostFunctions(StringBuffer buf) {
        if (postFunctions.size() > 0) {
            buf.append("<post-functions>");

            Iterator iter = postFunctions.iterator();

            while (iter.hasNext()) {
                FunctionDescriptor function = (FunctionDescriptor) iter.next();
                buf.append(function.getXML());
            }

            buf.append("</post-functions>");
        }
    }

}
